/**
 * 
 */
package com.demo2do.boyle.backend.security;

import java.util.List;
import java.util.Map;

import org.apache.commons.collections.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import com.demo2do.boyle.backend.service.system.PrincipalService;
import com.demo2do.boyle.common.entity.system.Principal;
import com.demo2do.core.cache.CacheAccessor;


/**
 * 
 * @author downpour
 */
public class ApplicationAuthenticationProvider implements UserDetailsService {

	private static final Logger logger = LoggerFactory.getLogger(ApplicationAuthenticationProvider.class);
	
	private CacheAccessor cacheAccessor;
	
	private PrincipalService principalService;
	
	/**
     * @param cacheAccessor the cacheAccessor to set
     */
    public void setCacheAccessor(CacheAccessor cacheAccessor) {
        this.cacheAccessor = cacheAccessor;
    }
    /*
     * @param principalService the principalService to set
     */
    public void setPrincipalService(PrincipalService principalService) {
    	this.principalService = principalService;
    }
	
	/* (non-Javadoc)
	 * @see org.springframework.security.core.userdetails.UserDetailsService#loadUserByUsername(java.lang.String)
	 */
	@SuppressWarnings({"unchecked"})
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

	    Principal principal = principalService.loadPrincipal(username);
	    
	    if (principal == null) {
            throw new UsernameNotFoundException("ApplicationAuthenticationProvider#loadUserByUsername() - user not found.");
        }
        
        // ======= initialize other user properties =======
        
        // 1. initialize role based resources
        Map<String, List<String>> resources = (Map<String, List<String>>) cacheAccessor.evaluate("resources['" + principal.getAuthority() + "']");
        
        if(MapUtils.isNotEmpty(resources)) {
            principal.initResources(resources);
        }
        
        // 2. initialize businessUnit by logger its name
        
        logger.info("ApplicationAuthenticationProvider#loadUserByUsername() - principal " + principal.getName() + " ] is found to login. ");
        
		return principal;

	}

}
